import { getToken } from '@/utils/common'
import EventFilePreview from './EventFilePreview.js'
import { downloadByUrl } from '@/utils/download'
/**
 *    此混入只存放基本处理方法，其它组件需求需要外层引入
 *    value：绑定数据结构，value数据格式化看watch
 *    formatValue：从fileList转换成value绑定的数据格式
 *    parseValue：从value转换成fileList数据格式
 *
 *        约定fileList必须有key做为文件唯一性验证
 */
export default {
    props: {
        disabled: Boolean,

        accept: {
            type: String,
            default: '.png,.jpg,.jpeg,.pdf,.doc,.docx,.ppt,.pptx,.txt,.mp4'
        },
        limit: {
            type: Number,
            default: 9
        },
        headers: {
            type: Object,
            default() {
                return {
                    Authorization: 'Bearer ' + getToken()
                }
            }
        },
        uploadUrl: {
            type: String,
            default: '/file/base/common/upload'
        },
        // 是否可以下载
        showDownload: {
            type: Boolean,
            default: true
        },
        // 单文件大小
        maxSize: {
            type: Number,
            default: 10
        }
    },
    data() {
        return {
            uploadFileList: []
        }
    },
    computed: {
        url() {
            return process.env.VUE_APP_BASE_API + this.uploadUrl
        }
    },
    methods: {
        // 上传前文件处理
        beforeUpload(file) {
            if (file.size / 1024 / 1024 > this.maxSize) {
                this.$message.error(`单个文件上传大小不得超过${this.maxSize}M`)
                return false
            }
            const fileType = file.name.substring(file.name.lastIndexOf('.')).toLowerCase()
            const acceptArr = this.accept.split(',')
            // 判断上传文件格式
            if (acceptArr.indexOf(fileType) === -1) {
                this.$message.error(`上传格式仅支持${this.accept.replaceAll('.', '').replaceAll(',', '、')}`)
                return false
            } else {
                if (['.png', '.jpg', '.jpeg', '.bmp'].includes(fileType)) {
                    file.resourceType = 1
                    file.url = URL.createObjectURL(file)
                } else if (['.mp4', '.avi'].includes(fileType)) {
                    file.resourceType = 2
                } else {
                    file.resourceType = 3
                }
            }
            this.$set(file, '_status', 'loading')
            this.$set(file, 'percentage', 0)
            this.uploadFileList.push(file)
        },
        // 超出上传数量
        onExceed() {
            this.$message.error('最多上传' + this.limit + '个文件!')
        },
        // 从files,取file的文件索引
        findFileIndex(file, files) {
            return files.findIndex((item) => item.key === file.key)
        },
        // 预览
        handlerPreview(file) {
            const files = this.uploadFileList.filter((item) => item._status === 'done')
            files.map((item) => {
                if (!item.resourceUrl) item.resourceUrl = item.url || item.resourceUrl || item.key
            })
            EventFilePreview.show({
                files,
                showDownload: this.showDownload,
                initialIndex: this.findFileIndex(file, files)
            })
        },
        // 移除
        async handleRemove(file) {
            const index = this.findFileIndex(file, this.uploadFileList)
            if (index === -1) return
            this.uploadFileList.splice(index, 1)
            this.submitEvent()
        },
        // 上传成功
        fileUploadSuccess(response, file) {
            if (response.code === 200) {
                file._status = 'done'
                this.$forceUpdate()
                this.onSuccess(response, file)
                this.errorMsg = null
            } else {
                file._status = 'error'
                this.errorMsg = response.msg || '文件上传失败'
                this.$message.error(this.errorMsg)
                this.uploadFileList.splice(this.uploadFileList.indexOf(file), 1)
                this.$forceUpdate()
            }
            if (this.uploadFileList.every((item) => item._status !== 'loading')) this.submitEvent()
        },
        // 更新绑定数据
        submitEvent() {
            const files = this.uploadFileList.filter((item) => item._status === 'done')
            const value = this.formatValue(files)
            this.$emit('input', value)
            this.$emit('change', value)
            this._dispatch('ElFormItem', 'el.form.change', value)
        },
        // 下载
        handlerDownload(file) {
            downloadByUrl(file.resourceUrl, file.fileName || this.downloadFileName + new Date().valueOf())
        },
        // 进度
        onProgress(event, file) {
            file.percentage = event.percent
            this.$forceUpdate()
        }
    },
    watch: {
        // 初始化绑定数据，当数据变化， 过滤重复数据，维持uploadFileList的数据
        value: {
            handler(val) {
                if (val) {
                    val = this.parseValue(val)
                    val.map((item) => {
                        const node = this.uploadFileList.find((file) => item.key === file.key)
                        if (node) {
                            Object.assign(node, item)
                        } else {
                            this.uploadFileList.push({
                                ...item,
                                _status: 'done'
                            })
                        }
                    })
                }
            },
            immediate: true
        }
    }
}
